﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mighty.Brain;
using Mighty.Common;
using System.Collections;

namespace Mighty.Brain
{
    public class KRBrain : BasicBrain
    {
        /// <summary>
        /// 각 플레이어가 가지게 되는 게임에 대한 정보, 각 이벤트가 호출되기 전에 gameInfo에는 항상 최신의 정보가
        /// 업데이트되어 있다
        /// </summary>
        public GameInfo gameInfo;

        /// <summary>
        /// 게임시작
        ///  * 매 게임마다 초기화해야할 코드가 있다면 여기에 넣어라
        /// </summary>
        public override void GameStartEvent()
        {
        }

        /// <summary>
        /// 베팅시작
        ///  * 카드를 나누어 주고 호출된다. gameInfo.myCards를 참고
        /// </summary>
        public override void BettingReadyEvent()
        {
        }

        /// <summary>
        /// 베팅차례
        ///  * 지금까지 배팅된 정보(gameInfo.bettingHistory) 또는 마지막 pass가 아닌 베팅정보 gameInfo.betting를 참고하여 베팅을 결정한다
        /// </summary>
        /// <remarks>
        /// [기본행동] 베팅리밋(betting.limit)이 15이하 이면 베팅리밋을 +1하고 노기루다(Giruda.NoGiruda)로 베팅한다
        /// </remarks>
        public override Betting BettingTicEvent()
        {
            int score = 0;
            int cnt = 0;

            Betting betting = new Betting();

            betting.isPass = true;          //패스가 되서 자기 차례까지 오는 거
            //이 앞까지의 사람이 패스를 했을 경우

            if (gameInfo.betting.limit == 0)
            {
                Betting previousBetting = gameInfo.betting;

                int a;        //받은 카드의 무늬에 따라 나눌 경우

                int[] cardShape = new int[4] { 0, 0, 0, 0 };    //int[0]=Clover,    int[1]=Diamond, int[2]=Heart,    int[3]=Spade

                for (int i = 0; i < 4; i++)
                {
                    cardShape[i] = 0;
                }

                for (a = 0; a < 10; a++)
                {

                    if (gameInfo.myCards[a].shape == Shape.Clover)
                        cardShape[0]++;
                    else if (gameInfo.myCards[a].shape == Shape.Diamond)
                        cardShape[1]++;
                    else if (gameInfo.myCards[a].shape == Shape.Heart)
                        cardShape[2]++;
                    else if (gameInfo.myCards[a].shape == Shape.Spade)
                        cardShape[3]++;
                }

                int shape = 0;

                if (cardShape[0] == 3 || cardShape[1] == 3 || cardShape[2] == 3 || cardShape[3] == 3)
                {
                    for (cardShape[shape] = 0; cardShape[shape] == 3; shape++)
                    {
                        cnt = shape;
                    }

                    if (gameInfo.myCards[a].number == 14 && gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 2;
                    }
                    else if (gameInfo.myCards[a].number == 14 || gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score++;
                    }
                }

                if (cardShape[0] == 4 || cardShape[1] == 4 || cardShape[2] == 4 || cardShape[3] == 4)
                {

                    for (cardShape[shape] = 0; cardShape[shape] == 3; shape++)
                    {
                        cnt = shape;
                    }
                    if (gameInfo.myCards[a].number == 14 && gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 3;
                    }
                    else if (gameInfo.myCards[a].number == 14 || gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 2;
                    }
                }

                if (cardShape[0] == 5 || cardShape[1] == 5 || cardShape[2] == 5 || cardShape[3] == 5)
                {

                    for (cardShape[shape] = 0; cardShape[shape] == 3; shape++)
                    {
                        cnt = shape;
                    }
                    if (gameInfo.myCards[a].number == 14 && gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 4;
                    }
                    else if (gameInfo.myCards[a].number == 14 || gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 3;
                    }
                }

                if (betting.limit == 0 && score >= 1)
                {
                    if (score == 1)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 13;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 13;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 13;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 13;
                                break;
                            default:
                                break;
                        }
                    }
                    else if (score == 2)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 14;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 14;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 14;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 14;
                                break;

                        }
                    }
                    else if (score == 3)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 15;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 15;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 15;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 15;
                                break;
                        }
                    }
                    else if (score == 4)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 16;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 16;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 16;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 16;
                                break;
                        }












                        /*
                    for(int i=0; i<=10; i++)
                        HandedCard c=gameinfo.myCards[i];


                    int s=(int)s.Shape;
    
                         */

                        if (previousBetting.limit < 15)
                        {
                            betting.isPass = false;
                            betting.giruda = Giruda.NoGiruda;
                            betting.limit = previousBetting.limit + 1;
                        }
                    }
                    else
                    {
                        betting.isPass = false;
                        betting.giruda = Giruda.NoGiruda;
                        betting.limit = 13;
                    }
                }

                return betting;

            }


            if (gameInfo.betting.limit > 0)
            {
                Betting previousBetting = gameInfo.betting;

                int a;        //받은 카드의 무늬에 따라 나눌 경우

                int[] cardShape = new int[4] { 0, 0, 0, 0 };    //int[0]=Clover,    int[1]=Diamond, int[2]=Heart,    int[3]=Spade

                for (int i = 0; i < 4; i++)
                {
                    cardShape[i] = 0;
                }

                for (a = 0; a < 14; a++)
                {

                    if (gameInfo.myCards[a].shape == Shape.Clover)
                        cardShape[0]++;
                    else if (gameInfo.myCards[a].shape == Shape.Diamond)
                        cardShape[1]++;
                    else if (gameInfo.myCards[a].shape == Shape.Heart)
                        cardShape[2]++;
                    else if (gameInfo.myCards[a].shape == Shape.Spade)
                        cardShape[3]++;
                }

                int shape = 0;

                if (cardShape[0] == 3 || cardShape[1] == 3 || cardShape[2] == 3 || cardShape[3] == 3)
                {
                    for (cardShape[shape] = 0; cardShape[shape] == 3; shape++)
                    {
                        cnt = shape;
                    }

                    if (gameInfo.myCards[a].number == 14 && gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 2;
                    }
                    else if (gameInfo.myCards[a].number == 14 || gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score++;
                    }
                }

                if (cardShape[0] == 4 || cardShape[1] == 4 || cardShape[2] == 4 || cardShape[3] == 4)
                {

                    for (cardShape[shape] = 0; cardShape[shape] == 3; shape++)
                    {
                        cnt = shape;
                    }
                    if (gameInfo.myCards[a].number == 14 && gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 3;
                    }
                    else if (gameInfo.myCards[a].number == 14 || gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 2;
                    }
                }

                if (cardShape[0] == 5 || cardShape[1] == 5 || cardShape[2] == 5 || cardShape[3] == 5)
                {

                    for (cardShape[shape] = 0; cardShape[shape] == 3; shape++)
                    {
                        cnt = shape;
                    }
                    if (gameInfo.myCards[a].number == 14 && gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 4;
                    }
                    else if (gameInfo.myCards[a].number == 14 || gameInfo.myCards[a].shape == Shape.Joker)
                    {
                        score += 3;
                    }
                }

                if (betting.limit == 0 && score >= 1)
                {
                    if (score == 1)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 13;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 13;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 13;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 13;
                                break;
                            default:
                                break;
                        }
                    }
                    else if (score == 2)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 14;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 14;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 14;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 14;
                                break;

                        }
                    }
                    else if (score == 3)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 15;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 15;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 15;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 15;
                                break;
                        }
                    }
                    else if (score == 4)
                    {
                        switch (cnt)
                        {
                            case 0:
                                betting.isPass = false;
                                betting.giruda = Giruda.Clover;
                                betting.limit = 16;
                                break;
                            case 1:
                                betting.isPass = false;
                                betting.giruda = Giruda.Diamond;
                                betting.limit = 16;
                                break;
                            case 2:
                                betting.isPass = false;
                                betting.giruda = Giruda.Heart;
                                betting.limit = 16;
                                break;
                            case 3:
                                betting.isPass = false;
                                betting.giruda = Giruda.Spade;
                                betting.limit = 16;
                                break;
                        }












                        /*
                    for(int i=0; i<=10; i++)
                        HandedCard c=gameinfo.myCards[i];


                    int s=(int)s.Shape;
    
                         */

                        if (previousBetting.limit < 15)
                        {
                            betting.isPass = false;
                            betting.giruda = Giruda.NoGiruda;
                            betting.limit = previousBetting.limit + 1;
                        }
                    }
                    else
                    {
                        betting.isPass = false;
                        betting.giruda = Giruda.NoGiruda;
                        betting.limit = 13;
                    }
                }
            }

            return betting;
        }


        /// <summary>
        /// 다른사람의 베팅 정보
        /// </summary>
        public override void BettingTalkEvent()
        {
        }

        /// <summary>
        /// 베팅완료, 주공이 정해졌다. 베팅이 끝났을 경우 처리할 코드가 있다면 여기에 하라.
        /// </summary>
        public override void BettingCompleteEvent()
        {
        }

        /// <summary>
        /// (주공)카드선택, 13장의 카드중 10장의 카드선택. 버릴3장의 카드에 cmdRemove=true로 설정해주어야 한다
        /// 만약 정확히 3장의 카드가 선택되지 않았을 경우에는 새로추가된 3장의 카드가 그대로 버려진다.
        /// ChoiceCardEvent 가 호출된 후에는 선택된 10장의 카드는 myCards[0]부터 차례대로 배치되고 버려진 3장의 카드는
        /// myCards[10]에서부터 배치되어 나중에 어떤 카드가 버려졌는지 알수 있게 해준다
        /// </summary>
        /// <remarks>
        /// [기본행동] 추가된 3장의 카드를 그대로 버린다
        /// </remarks>
        public override HandedCard[] ChoiceCardEvent()
        {
            for (int i = 0; i <= 9; i++)
            {
                gameInfo.myCards[i].cmdRemove = false;
            }
            for (int i = 10; i <= 12; i++)
            {
                gameInfo.myCards[i].cmdRemove = true;
            }
            return gameInfo.myCards;
        }


        /// <summary>
        /// 최종베팅정보, 기루다무늬변경가능. 기루다를 변경할 경우 최소+2된 limit정보를 리턴해야 한다
        /// </summary>
        /// <remarks>
        /// [기본행동] 아무런 변경도 하지 않는다
        /// </remarks>
        public override Betting LastBettingEvent()
        {
            return gameInfo.betting;
        }

        /// <summary>
        /// 주공의 최종베팅정보
        /// </summary>
        public override void LastBettingTalkEvent()
        {
        }

        /// <summary>
        /// (주공)프랜드선택. 프랜드를 선택하는 방법은 노프랜드(FriendPlayer.HowToSelect.nofriend),
        /// 초구프랜드(FriendPlayer.HowToSelect.firstwin),카드프랜드(FriendPlayer.HowToSelect.card)가 있다.
        /// </summary>
        /// <remarks>
        /// [기본행동] 초구프랜드를 선택한다
        /// </remarks>
        public override FriendPlayer ChoiceFriendEvent()
        {
            gameInfo.friend.howToSelect = FriendPlayer.HowToSelect.firstwin;
            return gameInfo.friend;
        }

        /// <summary>
        /// 주공의 프랜드 정보
        /// </summary>
        public override void ChoiceFriendTalkEvent()
        {
        }

        /// <summary>
        /// 각라운드의시작
        ///  * 매라운드마다 초기화할 코드가 있다면 이부분에 들어가게 된다
        /// </summary>
        public override void RoundReadyEvent()
        {

        }

        /// <summary>
        /// 카드낼차례
        ///  * 각 사용자의 턴에 한번씩 호출되며 낼 카드를 결과값으로 리턴해야 한다. 
        ///  * 사용가능한 카드에는 myCards[i].isPossible 속성이 true로 설정되어 있다. 
        ///  * 만약 사용불가능한 카드를 낼 경우에 시스템은 카드배열에서 제일 처음 만나는 사용가능한 카드를 골라서 사용한다
        /// </summary>
        /// <remarks>
        /// [기본행동] 가능한 카드중에서 랜덤하게 하나의 카드를 선택한다
        /// </remarks>

        public override HandedCard RoundTicEvent()
        {
            ArrayList possibleCards = new ArrayList();
            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible) possibleCards.Add(card);
            }

            Random r = new Random();
            int k = r.Next(possibleCards.Count);

            return (HandedCard)possibleCards[k];
        }



        /// <summary>
        /// 다른사람의 카드 정보
        /// </summary>
        public override void RoundCardThrowEvent()
        {
        }

        /// <summary>
        /// 각라운드의종료, 각 라운드가 종료되면 호출된다. 각 라운드의 승자는 gameinfo의 winner를 참조한다
        /// </summary>
        public override void RoundCompleteEvent()
        {

        }

        /// <summary>
        /// 게임의 종료, 게임이 종료되었을때 실행될 코드는 여기에 추가한다.
        /// </summary>
        public override void GameEndEvent()
        {

        }
    }
}
